﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Diagram
{
    [Serializable]
    public class Klasa : ElementNaDiagramie, ModelUML.iKlasaUML 
    {
        private List<Atrybut> atrybuty;        
        private List<Operacja> operacje;
        public Klasa(ModelUML.KlasaUML klasa)
        {
            element = klasa;
            klasa.lista_iKlas.Add(this);
            atrybuty = new List<Atrybut>();
            operacje = new List<Operacja>();
            for (int i = 0; i < klasa.IloscAtrybutow; i++)
            {
                Atrybut atr = new Atrybut(klasa.GetAtrybut(i));
                atr.ShowInGui = false;
                atrybuty.Add(atr);
            }
            for (int i = 0; i < klasa.IloscOperacji; i++)
            {
                Operacja ope = new Operacja(klasa.GetOperacje(i));
                ope.ShowInGui = false;
                operacje.Add(ope);
            }
        }
        public void SetElement(ModelUML.KlasaUML kl)
        {
            ElemenT = kl;
        }
        public void DodajAtrybut(ModelUML.AtrybutUML atrybut, bool showInGui)
        {
            ((ModelUML.KlasaUML)element).DodajAtrybut(atrybut);
            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                Atrybut tmpAtr = new Atrybut(atrybut);
                tmpAtr.ShowInGui = showInGui;
                kd.atrybuty.Add(tmpAtr);
            }
        }
        public void DodajAtrybutEnd(ModelUML.AtrybutUML atrybut, bool showInGui)
        {
            ((ModelUML.KlasaUML)element).DodajAtrybut(atrybut);
            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                Atrybut tmpAtr = new Atrybut(atrybut);
                tmpAtr.ShowInGui = showInGui;
                kd.atrybuty.Insert(0, tmpAtr);
            }
        }
        public Atrybut DodajAtrybut(Atrybut atrybut)
        {
            ((ModelUML.KlasaUML)element).DodajAtrybut((ModelUML.AtrybutUML)atrybut.element);
            atrybuty.Add(atrybut);
            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                if (kd != this)
                {
                    Atrybut tmpAtr = new Atrybut((ModelUML.AtrybutUML)atrybut.element);
                    tmpAtr.ShowInGui = false;
                    kd.atrybuty.Add(tmpAtr);
                }
            }
            return atrybut;
        }
        public Atrybut DodajAtrybut(String nazwa, String typ)
        {            
            ModelUML.AtrybutUML atr = ((ModelUML.KlasaUML)element).DodajAtrybut(nazwa, typ);
            if (atr == null) return null;
            Atrybut atrDiag = new Atrybut(atr);
            atrybuty.Add(atrDiag);

            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                if (kd != this)
                {
                    Atrybut tmpAtr = new Atrybut(atr);
                    tmpAtr.ShowInGui = false;
                    kd.atrybuty.Add(tmpAtr);
                }
            }
            return atrDiag;
        }
        private void UsunAtrybutNr(int num)
        {
            atrybuty.RemoveAt(num);
        }
        public void UsunAtrybut(Atrybut atr)
        {
            int poz = atrybuty.IndexOf(atr);
            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                kd.UsunAtrybutNr(poz);
            }
            ((ModelUML.KlasaUML)element).UsunAtrybut((ModelUML.AtrybutUML)atr.element);
        }

        private void UsunOperacjeNr(int num)
        {
            operacje.RemoveAt(num);
        }
        public void UsunOperacje(Operacja ope)
        {
            int poz = operacje.IndexOf(ope);
            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                kd.UsunOperacjeNr(poz);
            }
            ((ModelUML.KlasaUML)element).UsunOperacje((ModelUML.OperacjaUML)ope.element);
        }
        public void DodajOperacjeEnd(ModelUML.OperacjaUML operacja, bool showInGui)
        {
            ((ModelUML.KlasaUML)element).DodajOperacje(operacja);
            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                Operacja tmpOp = new Operacja(operacja);
                tmpOp.ShowInGui = showInGui;
                kd.operacje.Insert(0,tmpOp);
            }
        }
        public void DodajOperacje(ModelUML.OperacjaUML operacja, bool showInGui)
        {
            ((ModelUML.KlasaUML)element).DodajOperacje(operacja);
            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                Operacja tmpOp = new Operacja(operacja);
                tmpOp.ShowInGui = showInGui;
                kd.operacje.Add(tmpOp);
            }
        }
        public Operacja DodajOperacje(Operacja operacja)
        {
            ((ModelUML.KlasaUML)element).DodajOperacje((ModelUML.OperacjaUML)operacja.element);
            operacje.Add(operacja);
            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                if (kd != this)
                {
                    Operacja tmpOp = new Operacja((ModelUML.OperacjaUML)operacja.element);
                    tmpOp.ShowInGui = false;
                    kd.operacje.Add(tmpOp);
                }
            }
            operacja.ShowInGui = true;
            return operacja;
        }
        public Operacja DodajOperacje(String nazwa, String typ)
        {
            ModelUML.OperacjaUML op = ((ModelUML.KlasaUML)element).DodajOperacje(nazwa, typ);
            Operacja opDiag = new Operacja(op);            
            operacje.Add(opDiag);

            foreach (Klasa kd in ((ModelUML.KlasaUML)element).lista_iKlas)
            {
                if (kd != this)
                {
                    Operacja tmpOp = new Operacja(op);
                    tmpOp.ShowInGui = false;
                    kd.operacje.Add(tmpOp);
                }
            }
            opDiag.ShowInGui = true;
            return opDiag;
        }
        public int IloscOperacji
        {
            get
            {
                return operacje.Count;
            }
        }
        public int IloscAtrybutow
        {
            get
            {
                return atrybuty.Count;
            }
        }
        public Atrybut GetAtrybut(int index)
        {
            return atrybuty[index];
        }
        public Operacja GetOperacje(int index)
        {
            return operacje[index];
        }
    }
}
